#pragma once


#include <map>
#include <string>
#include "Singleton.h"


class ApiOrderCache 
{
public:
    struct Data
    {
        std::int32_t result;
        std::uint32_t uid;
        std::string provider;
        std::uint32_t agencyid;
        std::uint32_t gameid;
        std::uint64_t cycle;
        std::uint64_t orderid;
        std::uint64_t optime;
        std::uint64_t balance;
        std::uint64_t bet;
        std::uint64_t winlose;
        std::uint64_t preserve;
        std::uint64_t associatedorder;

        std::int64_t expire_time;

        Data()
        {
            result              = 0  ;
            uid                 = 0  ;
            provider            = ""  ;
            agencyid            = 0  ;
            gameid              = 0  ;
            cycle               = 0  ;
            orderid             = 0  ;
            optime              = 0  ;
            balance             = 0  ;
            bet                 = 0  ;
            winlose             = 0  ;
            preserve            = 0  ;
            associatedorder     = 0  ;
        }

        Data(const Data& data)
        {
            result              = data.result           ;
            uid                 = data.uid              ;
            provider            = data.provider         ;
            agencyid            = data.agencyid         ;
            gameid              = data.gameid           ;
            cycle               = data.cycle            ;
            orderid             = data.orderid          ;
            optime              = data.optime           ;
            balance             = data.balance          ;
            bet                 = data.bet              ;
            winlose             = data.winlose          ;
            preserve            = data.preserve         ;
            associatedorder     = data.associatedorder  ;
        }
        Data(Data&& data)
        {
            result              = data.result               ;
            uid                 = data.uid                  ;
            provider            = std::move(data.provider)  ;
            agencyid            = data.agencyid             ;
            gameid              = data.gameid               ;
            cycle               = data.cycle                ;
            orderid             = data.orderid              ;
            optime              = data.optime               ;
            balance             = data.balance              ;
            bet                 = data.bet                  ;
            winlose             = data.winlose              ;
            preserve            = data.preserve             ;
            associatedorder     = data.associatedorder      ;
        }
        Data& operator = (const Data& data)
        {
            result              = data.result           ;
            uid                 = data.uid              ;
            provider            = data.provider         ;
            agencyid            = data.agencyid         ;
            gameid              = data.gameid           ;
            cycle               = data.cycle            ;
            orderid             = data.orderid          ;
            optime              = data.optime           ;
            balance             = data.balance          ;
            bet                 = data.bet              ;
            winlose             = data.winlose          ;
            preserve            = data.preserve         ;
            associatedorder     = data.associatedorder  ;
            return *this;
        }
        Data& operator = (Data&& data)
        {
            result              = data.result               ;
            uid                 = data.uid                  ;
            provider            = std::move(data.provider)  ;
            agencyid            = data.agencyid             ;
            gameid              = data.gameid               ;
            cycle               = data.cycle                ;
            orderid             = data.orderid              ;
            optime              = data.optime               ;
            balance             = data.balance              ;
            bet                 = data.bet                  ;
            winlose             = data.winlose              ;
            preserve            = data.preserve             ;
            associatedorder     = data.associatedorder      ;
            return *this;
        }
    };

public:
    ApiOrderCache() = default;
    virtual ~ApiOrderCache() = default;

public:
    static ApiOrderCache* Instance()
	{
		return CSingleton<ApiOrderCache>::Instance();
	}

public:
	void CacheBetFailed(std::uint64_t order_id, Data&& data);
	Data* CheckBetFailed(std::uint64_t order_id);
	void ClearBetFailed(std::uint64_t order_id);
    
	void CacheCancleBet(std::uint64_t order_id, std::uint64_t expire_time);
	bool CheckCancleBet(std::uint64_t order_id);
	void ClearCancleBet(std::uint64_t order_id);

	void CacheBetAndWinFailed(std::uint64_t order_id, Data&& data);
	Data* CheckBetAndWinFailed(std::uint64_t order_id);
	void ClearBetAndWinFailed(std::uint64_t order_id);
    
	void CacheCancleBetAndWin(std::uint64_t order_id, std::uint64_t expire_time);
	bool CheckCancleBetAndWin(std::uint64_t order_id);
	void ClearCancleBetAndWin(std::uint64_t order_id);

public:
    void Reset();

private:
    std::map<std::uint64_t, Data> m_bet_failed_group;
    std::map<std::uint64_t, std::uint64_t> m_cancle_bet_group;
    std::map<std::uint64_t, Data> m_bet_and_win_failed_group;
    std::map<std::uint64_t, std::uint64_t> m_cancle_bet_and_win_group;
};













